/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 *--------------------------------------------------------*/

import * as vscode from 'vscode';
import { subscribeToDocumentChangesRename, RENAME_MENTION } from './diagnostics-rename';
import { CommonUnit } from './lib/commonUnit';

const COMMAND_RENAME = 'variable-rename.rename';

export function activate(context: vscode.ExtensionContext) {
	const renameDiagnostics = vscode.languages.createDiagnosticCollection("rename");
	context.subscriptions.push(renameDiagnostics);
	subscribeToDocumentChangesRename(context, renameDiagnostics);

	// show :)
	// context.subscriptions.push(
	// 	vscode.languages.registerCodeActionsProvider('typescript', new RenameLintAndInsert(), {
	// 		providedCodeActionKinds: RenameLintAndInsert.providedCodeActionKinds
	// 	}));

	// show quick fix
	context.subscriptions.push(
		vscode.languages.registerCodeActionsProvider('typescript', new RenameQuickFix(), {
			providedCodeActionKinds: RenameQuickFix.providedCodeActionKinds
		}));
	context.subscriptions.push(
		vscode.commands.registerCommand(COMMAND_RENAME, (diagnostic: vscode.Diagnostic) => {
			// vscode.env.openExternal(vscode.Uri.parse('https://baidu.com'));

			renameCoreMethod(diagnostic.range);
		})
	);


}

/**
 * Provides code actions for converting :) to a smiley emoji.
 */
export class RenameLintAndInsert implements vscode.CodeActionProvider {

	public static readonly providedCodeActionKinds = [
		vscode.CodeActionKind.QuickFix
	];

	public provideCodeActions(document: vscode.TextDocument, range: vscode.Range): vscode.CodeAction[] | undefined {
		if (!this.isAtStartOfSmiley(document, range)) {
			return;
		}

		const replaceWithSmileyCatFix = this.createFix(document, range, '😺');

		const replaceWithSmileyFix = this.createFix(document, range, '😀');
		// Marking a single fix as `preferred` means that users can apply it with a
		// single keyboard shortcut using the `Auto Fix` command.
		replaceWithSmileyFix.isPreferred = true;

		const replaceWithSmileyHankyFix = this.createFix(document, range, '💩');

		const commandAction = this.createCommand();

		return [
			replaceWithSmileyCatFix,
			replaceWithSmileyFix,
			replaceWithSmileyHankyFix,
			commandAction
		];
	}

	private isAtStartOfSmiley(document: vscode.TextDocument, range: vscode.Range) {
		const start = range.start;
		const line = document.lineAt(start.line);
		return line.text[start.character] === '-' && line.text[start.character + 1] === '-';
	}

	private createFix(document: vscode.TextDocument, range: vscode.Range, emoji: string): vscode.CodeAction {
		const fix = new vscode.CodeAction(`Convert to ${emoji}`, vscode.CodeActionKind.QuickFix);
		fix.edit = new vscode.WorkspaceEdit();
		fix.edit.replace(document.uri, new vscode.Range(range.start, range.start.translate(0, 2)), emoji);
		return fix;
	}

	private createCommand(): vscode.CodeAction {
		const action = new vscode.CodeAction('Rename with --', vscode.CodeActionKind.Empty);
		action.command = { command: COMMAND_RENAME, title: 'rename --', tooltip: 'This will rename ---' };
		return action;
	}
}



export class RenameQuickFix implements vscode.CodeActionProvider {

	public static readonly providedCodeActionKinds = [
		vscode.CodeActionKind.QuickFix
	];

	provideCodeActions(document: vscode.TextDocument, range: vscode.Range | vscode.Selection, context: vscode.CodeActionContext, token: vscode.CancellationToken): vscode.CodeAction[] {
		// Marking a single fix as `preferred` means that users can apply it with a
		// single keyboard shortcut using the `Auto Fix` command.
		// for each diagnostic entry that has the matching `code`, create a code action command
		let filterList = context.diagnostics.filter(diagnostic => diagnostic.code === RENAME_MENTION);
		let actionList = filterList.flatMap(diagnostic => [this.createCommandCodeAction(diagnostic)]);

		return actionList;
	}

	private createCommandCodeAction(diagnostic: vscode.Diagnostic): vscode.CodeAction {
		const action = new vscode.CodeAction('Yes, this will rename', vscode.CodeActionKind.QuickFix);

		action.command = { command: COMMAND_RENAME, arguments: [diagnostic], title: 'Rename variable', tooltip: 'This rename variable, and it\'s relative ..' };
		action.diagnostics = [diagnostic];
		action.isPreferred = true;
		return action;
	}
}

function renameCoreMethod(range?: vscode.Range) {
	const editor = vscode.window.activeTextEditor;
	if (editor) {
		const document = editor.document;
		range = range || editor.selection;

		// get the word within the selection
		const word = document.getText(range);
		let newWord = word.toLowerCase();
		editor.edit(editorBuilder => {
			editorBuilder.replace(range!, newWord);
		});
	}
}